﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace SimplexEngine
{
    public class Root
    {
        private Root() 
        {
            content_system = new ContentSystem();
            render_system = new RenderSystem();
        }

        private static Root instance = new Root();
        public static Root Instance { get { return instance; } }

        /// <summary>
        /// init with game
        /// </summary>
        /// <param name="xna_game">game</param>
        /// <returns>true for success</returns>
        public Boolean Init(Game xna_game)
        {
            game = xna_game;
            ContentManager = xna_game.Content;

            return InternalInit();
        }

        private Boolean InternalInit()
        {
            scene_object_factories.Add("CAMERA", new CameraFactory());
            scene_object_factories.Add("STATICMESHENTITY", new StaticMeshEntityFactory());
            scene_object_factories.Add("ANIMATIONMESHENTITY", new AnimationMeshEntityFactory());
            scene_object_factories.Add("LIGHT", new LightFactory());
            return true;
        }

        public ContentSystem ContentSystem { get { return content_system; } }
        private ContentSystem content_system = null;

        internal ContentManager ContentManager { get; set; }

        private Int64 frame_number = 0;
        public Int64 FrameNumber { get { return frame_number; } }

        public void Update(GameTime game_time)
        {
            ++frame_number;
            // update content system
            content_system.Update(game_time);
            // update scene managers
            foreach (SceneManager scene_manager in scene_managers.Values)
                scene_manager.Update(game_time, frame_number);

        }

        public void Draw(GameTime game_time)
        {
            render_system.Draw(game_time, frame_number);
        }

        protected Dictionary<String, SceneObjectFactory> scene_object_factories = new Dictionary<String, SceneObjectFactory>();
        public Dictionary<String, SceneObjectFactory> SceneObjectFactories { get { return scene_object_factories; } }


        private RenderSystem render_system = null;
        public RenderSystem RenderSystem { get { return render_system; } }

        private Dictionary<String, SceneManager> scene_managers = new Dictionary<String, SceneManager>();
        public SceneManager CreateSceneManager(String name, String type)
        { 
            // TODO : create a scene manager factory

            SceneManager scene_manager = new SceneManager();
            scene_managers.Add(name, scene_manager);

            return scene_manager;
        }


        private Game game = null;
    }
}
